<template>
  <div class="employees-container">
    <div class="app-container">
      <PageTools>
        <template #left>
          <span>当前共有{{ total }}条纪录</span>
        </template>
        <template #right>
          <el-button type="danger" size="small" @click="handleDownload">
            普通excel导出
          </el-button>
          <el-button
            type="success"
            size="small"
            @click="$router.push('/import?type=user')"
          >
            excel导入
          </el-button>
          <el-button type="primary" size="small" @click="openDialogFn()">
            新增员工
          </el-button>
        </template>
      </PageTools>
      <!-- 卡片 -->
      <el-card v-loading="loading" style="margin-top: 10px">
        <el-table border :data="userlist">
          <el-table-column
            type="index"
            :index="indexMethod"
            label="序号"
            width="100"
          />
          <el-table-column label="姓名" prop="username" sortable="" />
          <el-table-column label="头像" prop="staffPhoto">
            <!-- 在员工列表在中添加员工头像 -->
            <!-- prop:el-table-column中使用prop属性，对应对象中的键名就能填入数据 -->
            <!-- 但拿到的是图片地址--str -->
            <!-- 我们可以使用<img>来显示图片 -->
            <!-- 就要使用作用域插槽 -->
            <template #default="{ row }">
              <!-- 我们发现有的是没有头像的，所以还要给这些员工设置个默认头像 -->
              <!-- 还有的有的员工是有头像地址的，但头像还是显示不了，因为图片地址对应的图片被删除了 -->
              <!-- 所以我们可以使用默认指令来检测看看图片是否有地址但加载失败 -->
              <img
                v-imgError="defaultImage"
                class="staff"
                :src="row.staffPhoto || defaultImage"
                alt=""
                @click="showCodeImg(row.staffPhoto)"
              />
            </template>
          </el-table-column>
          <el-table-column label="手机号" prop="mobile" sortable="" />
          <el-table-column label="工号" prop="workNumber" sortable="" />

          <!-- formatter：是table里的Table-column的属性--（是个方法），作用是用来格式化内容。 -->
          <!-- formatter方法的参数--Function(row, column, cellValue, index) 其中cellValue是内容信息 -->
          <el-table-column
            label="聘用形式"
            prop="formOfEmployment"
            :formatter="formatEmployment"
            sortable=""
          />

          <el-table-column label="部门" prop="departmentName" sortable="" />

          <el-table-column label="入职时间" prop="timeOfEntry" sortable="">
            <template #default="{ row }">
              {{ row.timeOfEntry | formatTime('YYYY年MM月DD日') }}
            </template>
          </el-table-column>

          <el-table-column label="操作" sortable="" fixed="right" width="280">
            <template #default="{ row }">
              <el-button
                type="text"
                size="small"
                @click="skipToEmployeeDetail(row.id)"
              >
                查看
              </el-button>
              <el-button type="text" size="small">转正</el-button>
              <el-button type="text" size="small">调岗</el-button>
              <el-button type="text" size="small">离职</el-button>
              <el-button
                type="text"
                size="small"
                @click="openRoleDialog(row.id)"
              >
                角色
              </el-button>
              <el-button type="text" size="small" @click="delUser(row.id)">
                删除
              </el-button>
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <el-pagination
          :current-page="page"
          :page-sizes="[5, 10, 20, 25]"
          :page-size="size"
          layout="total, sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </el-card>
      <AddEmployeeVue
        :dialog-visible.sync="dialogVisible"
        :title="title"
        @getDepartList="getUserList"
      />
    </div>
    <!-- canvas标签只是图形容器，您必须使用脚本来绘制图形。 -->
    <!-- 二维码弹层 -->
    <el-dialog
      title="二维码"
      :visible="showCode"
      width="300px"
      @close="showCode = false"
    >
      <canvas ref="codeImg" />
    </el-dialog>
    <!-- 角色弹层 -->
    <RoleDialog :show-role-dialog.sync="roleDialog" :user-id="userId" />
  </div>
</template>

<script>
import Qrcode from 'qrcode'
import { getUserListApi, delUserApi } from '@/api/employees'
import EmployeeEnum from '@/constant/employees'
import AddEmployeeVue from './components/add-employee.vue'
import { formatTime } from '@/filter/index'
import RoleDialog from './components/roleDialog.vue'
import Timg from '@/assets/common/head.jpg'
import mixin from '@/mixin'
export default {
  components: {
    AddEmployeeVue,
    RoleDialog
  },
  mixins: [mixin],
  data() {
    return {
      // 当前页数
      page: 1,
      // 每页数据的条数
      size: 5,
      // 当前页的员工列表
      userlist: [],
      // 总的数据条数
      total: 0,
      // 加载中的控制
      loading: false,
      // 弹层的控制
      dialogVisible: false,
      // 弹窗名称
      title: '',
      // 导出的excel文件名称--默认值：excel-list
      filename: '员工EXCEL列表',
      // 导出的文件类型--默认值：xlsx
      bookType: 'xlsx',
      // 单元格是否要自适应宽度--默认值：true
      autoWidth: true,
      // 列表的员工头像的默认地址
      defaultImage: Timg,
      // 控制二维码弹层的显隐
      showCode: false,
      // 控制角色弹层的显隐
      roleDialog: false,
      // 点击员工数据条的员工id
      userId: ''
    }
  },
  created() {
    this.getUserList()
  },
  methods: {
    // 获取员工列表
    async getUserList() {
      this.loading = true
      const res = await getUserListApi(this.page, this.size)
      // console.log(res)
      this.userlist = res.data.rows
      this.total = res.data.total
      this.loading = false
    },
    // 序号
    indexMethod(index) {
      // index:是当前页码数据数组的索引
      // 当前返回的序号
      // 前面一共有多少条数据=（当前页码-1）*每页的条数
      // 所以：当前页面的第一条数据的序号=前面一共有多少条数据+1
      // 那么但钱也买你的第二条数据的序号是多少呢？
      // =前面一共有多少条数据+1+当前这条数据的索引
      // console.log(index)
      return (this.page - 1) * this.size + index + 1
    },
    // 点击分页页码触发的操作
    async handleCurrentChange(val) {
      // console.log(`当前页: ${val}`)
      // 更新当前页页码
      this.page = val
      // 重新获取，新的页码数据
      this.getUserList()
    },
    // 更新每页的数据条数触发的操作
    handleSizeChange(val) {
      // console.log(`每页数据条数: ${val}`)
      // 更新每页数据条数
      this.size = val
      // 当更新完每页的数据条数之后，还要将当前页重置为第一页
      this.page = 1
      // 重新获取，新的页码数据，并且获取每页最新的数据条数
      this.getUserList()
    },
    // 格式化聘用形式
    // 我们可能这个项目多个地方显示聘用形式，我们也不可能将这行代码复制粘贴多次也，所以我们可以将这个操作进行封装。
    // 但是我们这里学习一个新的知识点-->常量抽离，用于判断的标识，抽离到常量模块。
    // 我们将cellValue这个变量进行封装【这个变量里面就是常量】，就这问题而言：我们定义一个数组，这个数组里面是我们的常量对象
    // EmployeeEnum 是我们常量对象
    // Array.find()  方法返回通过测试（函数内判断）的数组的第一个元素的值。
    formatEmployment(row, column, cellValue, index) {
      const obj = EmployeeEnum.hireType.find((item) => item.id === +cellValue)
      return obj ? obj.value : '未知'
      // console.log(row.formOfEmployment)
      // console.log(
      //   '行节点' + row,
      //   '列节点' + column,
      //   '内容信息【值】' + cellValue,
      //   '索引' + index
      // )
      // return row.formOfEmployment === 1 ? '正式' : '非正式'
    },
    // 删除员工
    delUser(id) {
      if (this.userDelBtn('USER_DEL')) {
        // true的话就是有权限
      } else {
        this.$message.error('你没有删除权限')
        return
      }
      this.$confirm('此操作将永久删除该员工, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(async () => {
          await delUserApi(id)
          // 我们还要进行判断我们删除的数据是不是第一页的最后一条数据，如果是，那就不要让页码数减一
          // 这一步要在删除完之后在执行，因为使用的是员工列表的长度进行判断的。
          if (this.userlist.length === 1 && this.page > 1) {
            this.page--
          }
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
          // 删除完之后还要重新获取员工列表进行渲染页面。
          this.getUserList()
        })
        .catch(() => {})
    },
    // 点击新增部门打开的弹层
    openDialogFn() {
      this.dialogVisible = true
      // this.Pdata = Pdata
      this.title = '新增员工'
      // // 获取部门负责人列表
      // this.$refs.adddept.getDepartUser()
    },
    // 员工列表导出成excel文件
    async handleDownload() {
      // 点击了按钮后，要拿到员工列表数据
      const res = await getUserListApi(1, this.total)
      const headersArr = [
        '姓名',
        '手机号',
        '工号',
        '聘用形式',
        '部门',
        '入职日期',
        '转正日期'
      ]
      const headersRelations = {
        姓名: 'username',
        手机号: 'mobile',
        入职日期: 'timeOfEntry',
        聘用形式: 'formOfEmployment',
        转正日期: 'correctionTime',
        工号: 'workNumber',
        部门: 'departmentName'
      }
      const list = this.formatEmployeeListData(
        res.data.rows,
        headersArr,
        headersRelations
      )
      // 复杂表头的部分
      const multiHeader = [['姓名', '主要信息', '', '', '', '', '部门']]
      // 需要合并的部分
      const merges = ['A1:A2', 'B1:F1', 'G1:G2']
      // this.downloadLoading = true
      // 我们是通过点击事件来导入Export2Excel这个包，如果我们多次触发点击事件，那么会不会多次导入这个包呢?
      // 答案当然是不会的，因为webpack帮我们处理了，所有的包只需要导入一次，以后的导入都不会被触发。
      // 我们引入的包怎么用呢？
      // 我们引入的包的方法和属性，全都包含在参数excel里面了。
      import('@/vendor/Export2Excel').then((excel) => {
        const data = list
        excel.export_json_to_excel({
          header: headersArr, // 导出excel的表头
          data, // 导出excel的表体，且还是个二维数组
          filename: this.filename, // 导出excel文件的文件名称
          autoWidth: this.autoWidth, // 是否自适应表格宽度
          bookType: this.bookType, // 导出的文件类型
          // 复杂表头的导出，需要下面这两个配置。
          multiHeader: multiHeader,
          merges: merges
        })
        // this.downloadLoading = false
      })
    },
    // 处理员工列表数据--处理成可以导出成excel的数据
    formatEmployeeListData(list, headersArr, headersRelations) {
      // console.log(list)
      // arr一维数组
      const arr = []
      list.forEach((item) => {
        const itArr = []
        headersArr.forEach((key) => {
          // console.log(item[headersRelations[key]])
          // 处理招聘方式
          // 首先要看看我们当前所遍历到的值是不是招聘形式的值，如果是，那就处理其值，并且改变他。
          if (headersRelations[key] === 'formOfEmployment') {
            // find()返回的是第一个符合条件的值
            const obj = EmployeeEnum.hireType.find(
              (ita) => ita.id === +item[headersRelations[key]]
            )
            item[headersRelations[key]] = obj ? obj.value : '未知'
          }
          if (
            ['timeOfEntry', 'correctionTime'].includes(headersRelations[key])
          ) {
            item[headersRelations[key]] = formatTime(
              item[headersRelations[key]],
              'YYYY年MM月DD日'
            )
          }
          itArr.push(item[headersRelations[key]])
        })
        // 处理聘用形式和时间
        // itArr.forEach((it) => {
        //   // console.log(it)
        //   const obj = EmployeeEnum.hireType.find((item) => item.id === +it)
        //   // return obj ? obj.value : '未知'
        //   if (obj) {
        //     // obj是对象，里面有id和value
        //     // console.log(obj)
        //     it = obj.value
        //     return obj.value
        //   } else {
        //     it = '未知'
        //     return '未知'
        //   }
        // })
        arr.push(itArr)
        // console.log(itArr)
      })
      // console.log(arr)
      return arr
    },
    // 跳转到员工详情页面
    skipToEmployeeDetail(id) {
      this.$router.push(`/employees/detail/${id}`)
    },
    // 显示二维码弹层
    showCodeImg(url) {
      this.showCode = true
      this.$nextTick(() => {
        Qrcode.toCanvas(this.$refs.codeImg, url)
      })
    },
    // 打开角色弹层
    openRoleDialog(id) {
      this.roleDialog = true
      this.userId = id
    }
    // // 员工页面按钮权限
    // userDelBtn(btn) {
    //   return this.$store.getters.roles.points.includes(btn)
    // }
  }
}
</script>

<style lang="scss" scoped>
.employees-container {
  .staff {
    width: 70px;
    height: 70px;
    border-radius: 50%;
  }
}
</style>
